///////////////////////////////////////////////////
/// tototoy Code
/// $Id: operate.h 26 2009-09-25 13:26:15Z tonyjobmails $
/// $Date: 2009-09-25 21:26:15 +0800 (五, 2009-09-25) $
/// $Author: tonyjobmails $
/// $Revision: 26 $
/// E-mail: tonyjobmails@gmail.com
/// filename: operate.h
/// function: 函数对象实现的操作机制
///
/// operate的实现是基于多态与函数对象的条件以及操作的集合，
/// 用于实现公共接口中传入参数以实现自定义条件和操作，
/// 实现代码重用，请合理设计接口。
///
/// 一种接口例子：
/// template<typename _T1, typename _T2>
/// void func_1(_T1 *target_set, int elem_num, op::action<_T1, _T2> *op);
/// 首先需要实现op为自定义操作，op中有内定条件，它是一个check_condition_list，
/// 这个条件列表的每一个元素是一个条件组，这个条件组可以是一些“相等”与“不相等”条件的“逻辑与”或“逻辑或”，
/// 形如：(x != 5 && x != 10 && x != 15)，这就是一个条件组
/// 这个条件列表可以有多个条件组，你可以定义条件组之间的逻辑关系，它们可以是"逻辑与"或"逻辑或"，
/// 形如：((x != 5 && x != 10 && x != 15) || (x == 0))，像这样两组条件组成了的一个条件列表，
/// 你可以如此使用，来对整个目标集合中符合你条件的元素进行你的自定义操作
///
/// 另一种接口例子
/// template<typename _T1, typename _T2>
/// void func_2(_T1 *target_set, int elem_num, op::check_codition<_T1, _T2> *cond, op::action<_T1, _T2> *op);
/// 首先需要实现cond为自定义条件(可以是由用户写条件类，也可以使用内部定义条件)，实现op为自定义操作，
/// 此接口可以理解为，对集合targe_set内的每一个满足条件cond的元素进行op操作
/// 由程序员自定义一个特定的条件类，来根据他们的特殊检查条件来筛选出符合他们条件的元素进行自定义操作，
/// 比如，你想对打印出从1900年到2009年所有闰年的年份，那你就要写一个action操作类，这个类实现打印年份，
/// 你还要写一个自定义的check_condition类，用来定义筛选条件，从一组年份中筛选出哪些是闰年，
/// 它可能是((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)，而我们内定的条件无法实现这种对检测目标
/// 进行一定操作(如year % 4)后再进行相等或不相等的判断，所以要程序员自定义一个条件检查类，来做这种检查。
///////////////////////////////////////////////////////////////
#ifndef __OPERATE__H
#define __OPERATE__H

#include <iostream>
#include <vector>

/// 定义操作机制
namespace op
 {
	/// 逻辑符
	enum logic_type
	{
		_LOGIC_AND = 0,
		_LOGIC_OR ,
	};

	/// 条件
	template<typename _T>
	struct _condition
	{
		_condition()
		{
			equal = true;
		}
		bool equal;				/// true是相等，false是不相等
		_T cond_data;	/// 比对条件
	};

	///////////////////////////////////////////////////////////////
	/// @brief 条件基类 <_TP作为operator的参数，_TC做为条件>
	/// @author tony
	template<typename _TP, typename _TC>
	class op_base
	{
		public:
			op_base()
			{
				this->logic =_LOGIC_AND;
			}
			virtual ~op_base() {};
			
			/// 设置逻辑
			void set_logic(unsigned char _logic)
			{
				if(_logic == _LOGIC_AND || _logic == _LOGIC_OR)
					logic = _logic;
			}
			/// 增加条件
			void add_condition(_condition<_TC> &cond)
			{
				this->condition_list.push_back(cond);
			}
			/// 清除条件
			void clear_condition()
			{
				this->condition_list.clear();
			}
			/// 得第一个条件
			bool get_first_condition(_condition<_TC> &cond)
			{
				_condition_vec_iter it = this->condition_list.begin();
				if(it == this->condition_list.end())
					return false;
				cond = *it;
				return true;
			}
			/// 得到条件个数
			int get_condition_num()
			{
				return this->condition_list.size();
			}
			
			virtual bool operator()(const _TP &data) = 0;
			
		protected:
			typedef std::vector<_condition<_TC> > _condition_vec;
			typedef typename _condition_vec::iterator _condition_vec_iter;
			_condition_vec condition_list;		/// 条件列表
			unsigned char logic;
	};
	///////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////
	/// @brief 条件类 <_TP作为operator的参数，_TC做为条件> 继承op_base
	/// @author tony
 	template<typename _T>
	class condition : public op_base<_T, _T>
	{
		public:
			condition() {};
			~condition() {};
			
			bool operator()(const _T &data)
			{
				_condition_vec_iter pos = this->condition_list.begin();
				for(; pos != this->condition_list.end(); ++pos)
				{
					/// 条件为相等判断
					if(pos->equal)
					{
						/// 逻辑为或，有一组条件为真，pass
						if(this->logic == _LOGIC_OR && data == pos->cond_data)
							return true;
						/// 逻辑为与，有一组条件为假，unpass
						if(this->logic == _LOGIC_AND && data != pos->cond_data)
							return false;
					}
					/// 条件为不相等判断
					else
					{
						/// 逻辑为或，有一组条件为真，pass
						if(this->logic == _LOGIC_OR && data != pos->cond_data)
							return true;
						/// 逻辑为与，有一组条件为假，unpass
						if(this->logic == _LOGIC_AND && data == pos->cond_data)
							return false;
					}
				}
				if(this->condition_list.empty())
					return true;
				else
					return ((this->logic == _LOGIC_OR) ? false : true);
			}
			
		public:
			typedef typename op_base<_T, _T>::_condition_vec_iter _condition_vec_iter;
	};
	///////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////
	/// @brief 操作基类
	/// @author tony
	/// 操作基类以多组条件为检测条件，实现了增加条件组等等方法，
	/// 作为条件检测和执行操作的一个共公基类
	template<typename _TP, typename _TC>
	class operate
	{
		public:
			operate()
			{
				this->logic = _LOGIC_AND;
			}
			virtual ~operate() {};
			
			/// 设置逻辑
			void set_logic(unsigned char _logic)
			{
				if(_logic == _LOGIC_AND || _logic == _LOGIC_OR)
					this->logic = _logic;
			}
			/// 增加条件指针
			void add_condition(op_base<_TP, _TC> *cond)
			{
				if(cond)
				{
					this->check_condition_list.push_back(cond);
				}
			}
			/// 清除条件
			void clear_condition()
			{
				this->check_condition_list.clear();
			}
			/// 检测条件
			bool pass_condition(_TP &data)
			{
				_check_condition_iter pos = this->check_condition_list.begin();
				for(; pos != this->check_condition_list.end(); ++pos)
				{
					if(*pos)
					{
						/// 逻辑为或，有一组条件为真，pass
						if(this->logic == _LOGIC_OR && (*(*pos))(data))
							return true;
						/// 逻辑为与，有一组条件为假，unpass
						if(this->logic ==  _LOGIC_AND && !(*(*pos))(data))
							return false;
					}
				}
				if(this->check_condition_list.empty())
					return true;
				else
					return ((this->logic == _LOGIC_OR) ? false : true);
			}
			
			virtual bool operator()(_TP &data) = 0;
			
		protected:
			typedef std::vector<op_base<_TP, _TC> *> _check_condition_vec;
			typedef typename _check_condition_vec::iterator _check_condition_iter;
			_check_condition_vec check_condition_list;		/// 条件检测列表
			unsigned char logic;
	 };
	 ///////////////////////////////////////////////////////////////

	 ///////////////////////////////////////////////////////////////
	 /// @brief 条件检测类
	 /// @author tony
	 /// 实现了条件检测，条件检测时，只要实例化此类，调用operator()方法
	 template<typename _TP, typename _TC>
	 class check_codition : public operate<_TP, _TC>
	 {
		public:
			check_codition() {};
			~check_codition() {};
			
			bool operator()(_TP &data)
			{
				return this->pass_condition(data);
			}
	 };
	 ///////////////////////////////////////////////////////////////

	 ///////////////////////////////////////////////////////////////
	 /// @brief 操作执行
	 /// @author tony
	 /// 使用时继承此类，实现基类operator()，对参数进行想要的操作
	 template<typename _TP, typename _TC>
	 class action : public operate<_TP, _TC>
	 {
		public:
			action() {};
			virtual ~action() {};
			
			virtual bool operator()(_TP &data) = 0;
	 };
	///////////////////////////////////////////////////////////////
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////华丽的分割线/////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// 定义常用的操作与条件，写在以下的部分，未完待续...
namespace op
{
	///////////////////////////////////////////////////////////////
	/// @brief 输出到std::out，需要类型_T支持操作符<<
	/// @author tony
	template<typename _T>
	class action_print : public action<_T, _T>
	{
		public:
			action_print() {};
			~action_print() {};
			
			bool operator()(_T &data)
			{
				if(this->pass_condition(data))
				{
					std::cout << data << " ";
					return true;
				}
				return false;
			}
	};
	///////////////////////////////////////////////////////////////
	
	///////////////////////////////////////////////////////////////
	/// 释放内存，设置指针为NULL
	template<typename _T>
	class action_free_pointer : public action<_T, _T>
	{
		public:
			action_free_pointer() {};
			~action_free_pointer() {};

			bool operator()(_T &data)
			{
				if(this->pass_condition(data))
				{
					delete data;
					data = NULL;
					return true;
				}
				return false;
			}
	};
	///////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////
	/// 释放内存，设置指针为NULL(对数组释放)
	template<typename _T>
	class action_free_pointer_group : public action<_T, _T>
	{
		public:
			action_free_pointer_group() {};
			~action_free_pointer_group() {};

			bool operator()(_T &data)
			{
				if(this->pass_condition(data))
				{
					delete data;
					data = NULL;
					return true;
				}
				return false;
			}
	};
	///////////////////////////////////////////////////////////////
};

#endif
